﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Application.Behavior.Observer
{
	public interface IObservable
	{
		void Afficher();
		void EnregistrerObservateur(IObservateur oObj);
		void SupprimerObservateur(IObservateur oObj);
	}

	public interface IObservateur
	{
		void Afficher();
		void Update(IObservable oObj);
	}

	public class StationMeteo : IObservable
	{
		// ATTRIBUTS
		private List<IObservateur> _listObservateur;

		private  float _fTemperature;
		public float Temperature
		{
			get { return _fTemperature; }
			set { _fTemperature = value; }
		}		
		private float _fHumidite;
		public float Humidite
		{
			get { return _fHumidite; }
			set { _fHumidite = value; }
		}	
		private float _fPression;
		public float Pression
		{
			get { return _fPression; }
			set { _fPression = value; }
		}	

		// CONSTRUCTEUR
		public StationMeteo()
		{
			_listObservateur	= new List<IObservateur>();
			_fTemperature		= 0.0F;
			_fHumidite			= 0.0F;
			_fPression			= 0.0F;
		}


		// METHODES

		public void Afficher()
		{
			Console.WriteLine("__________________________________________________");
			Console.WriteLine("Infos de la station météto :");
			Console.WriteLine("Température : {0}°C", _fTemperature);
			Console.WriteLine("Humidité : {0}%", _fHumidite);
			Console.WriteLine("Pression : {0}hPa", _fPression);
			Console.WriteLine("", _fPression);
			Console.WriteLine("Liste des abonnés :", _fPression);
			foreach (IObservateur oObj in _listObservateur)
			{
				oObj.Afficher();
			}
			Console.WriteLine("__________________________________________________");

		}

		public void EnregistrerObservateur(IObservateur oObj)
		{
			_listObservateur.Add(oObj);
		}

		public void SupprimerObservateur(IObservateur oObj)
		{
			_listObservateur.Remove(oObj);
		}

		private void NotifierObservateur()
		{
			foreach (IObservateur oObj in _listObservateur)
			{
				oObj.Update(this);
			}
		}

		public void ActualiserMesure()
		{
			Random randNum = new Random();

			_fTemperature	= randNum.Next(-50, 50);
			_fHumidite		= randNum.Next(0, 100);
			_fPression		= randNum.Next(868, 1087);

			NotifierObservateur();
		}
	}

	class AffichageMoyenneTemperature : IObservateur
	{
		// ATTRIBUTS		
		private List<float> _list;		

		//CONSTRUCTEURS
		public AffichageMoyenneTemperature()
		{
			this._list = new List<float>();
		}

		//METHODES
		public void Afficher()
		{			
			Console.WriteLine("Affichage moyenne température : {0}°C", GetMoyenne());
		}

		public void Update(IObservable oObservable)
		{
			if (oObservable is StationMeteo)
			{
				this._list.Add( ((StationMeteo)oObservable).Temperature );				
			}
		}

		private float GetMoyenne()
		{
			float dMoyenne = 0;
			int nNbValeur = _list.Count();
			if (nNbValeur != 0)
			{
				foreach (float dvaleur in _list)
				{
					dMoyenne += dvaleur;
				}

				dMoyenne = dMoyenne / nNbValeur;
			}

			return dMoyenne;
		}
	}

	class AffichageMoyenneHumidite : IObservateur
	{
		// ATTRIBUTS
		private List<float> _list;		

		//CONSTRUCTEURS
		public AffichageMoyenneHumidite()
		{
			_list = new List<float>();
		}

		//METHODES
		public void Afficher()
		{
			Console.WriteLine("Affichage moyenne humidité : {0}hPa", GetMoyenne());
		}

		public void Update(IObservable oObservable)
		{
			if (oObservable is StationMeteo)
			{
				this._list.Add(((StationMeteo)oObservable).Humidite);				
			}
		}

		private float GetMoyenne()
		{
			float dMoyenne = 0;
			int nNbValeur = _list.Count();
			if( nNbValeur != 0 )
			{
				foreach (float dvaleur in _list)
				{
					dMoyenne += dvaleur;
				}
				
				dMoyenne = dMoyenne / nNbValeur;
			}

			return dMoyenne;
		}
	}
}
